package cn.buk.tms.entity.bill;

import cn.buk.common.util.DecimalUtil;
import cn.buk.tms.entity.misc.Customer;
import cn.buk.tms.entity.misc.FlightInfo;
import com.fasterxml.jackson.annotation.JsonFormat;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.NamedQueries;
import jakarta.persistence.NamedQuery;
import jakarta.persistence.Table;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import jakarta.persistence.Transient;
import jakarta.persistence.UniqueConstraint;

/**
 * 退票
 */
@NamedQueries({
        @NamedQuery(
                name = "BillFlightRefund.searchMonthly",
                query = "select new cn.buk.tms.dto.ReportFlightRefundDto(o.balanceCode, o.ticketNo, " +
                        "b.opDate, o.psgName, o.remark, " +
                        "o.ticketAmount, o.airRefundCharge, o.serviceCharge, o.airlineRefundAmount, o.airlineRefundDate, " +
                        "o.passengerRefundAmount, o.psgRefundDate, o.reasonCode, " +
                        "b.op1, b.op2, b.op3, b.customerType, b.id, b.supplier, b.paymentMethod, o.customerId) " +
                        "from BillFlightRefundTicket o left join BillInfo b on (o.billNum = b.billNum and o.enterpriseId = b.enterpriseId)" +
                        " where o.enterpriseId = :enterpriseId and b.opDate >= :beginDate and b.opDate <= :endDate " +
                        " order by b.opDate, o.balanceCode, o.ticketNo"
        ),
        //以上查询语句，因为散客的customer_id字段为空，会导致散客的结果出不来，需要改进
})
@Entity
@Table(name = "bill_flight_refund_ticket",
        uniqueConstraints=@UniqueConstraint(name="uk_bill_flight_refund_ticket", columnNames={"enterprise_id", "balance_code", "ticket_no"}))
public class BillFlightRefundTicket {

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private int id;

    /**
     * 创建退票单的企业
     */
    @Column(name = "enterprise_id")
    private int enterpriseId;

    @Column(name = "balance_code", length = 3)
    private String balanceCode;

    /**
     * 要退的机票的票号
     */
    @Column(name = "ticket_no", length = 10)
    private String ticketNo;

    /**
     * 账单号
     */
    @Column(name = "bill_num", length = 32)
    private String billNum;

    /**
     * 客户类型
     * 0 - 代表散客
     * 1 - 代表企业客户
     */
    @Column(name="customer_type")
    private Integer customerType;

    /**
     * 冗余字段，应该和Order.customer值保持一致
     */
    @ManyToOne
    @JoinColumn(name="customer_id")
    private Customer customer;

    @Column(name = "customer_id", insertable = false, updatable = false)
    private Integer customerId;

    /**
     * 旅客姓名
     */
    @Column(name = "psg_name", length = 50)
    private String psgName;

    @Column(name = "pnr_no", length = 10)
    private String pnrNo;

    /**
     * 原付票款额
     */
    @Column(name = "ticket_amount")
    private double ticketAmount;

    /**
     * 企业收的退票服务费
     */
    @Column(name = "service_charge")
    private double serviceCharge;

    /**
     * 航司退票费
     */
    @Column(name = "air_refund_fee")
    private double airRefundCharge;

    /**
     * 航司实际退款金额（或同行退）
     */
    @Column(name = "airline_refund_amount")
    private Double airlineRefundAmount;

    /**
     * 实际退给客人的金额
     */
    @Column(name = "psg_refund_amount")
    private Double passengerRefundAmount;
    /**
     * 0 - 提交退票，等待处理
     * 1 - 我来处理
     * 2 - 已向航司提交退票
     * 8 - 航司已退，待退客人
     * 16 - 已退客人
     */
    private int status;

    @Column(length = 32)
    private String operator;

    /**
     * 出票员：处理退票
     */
    @Column(length = 32)
    private String ticketer;

    /**
     * 收款员（如果是月结订单，该值为空)
     */
    @Column(length = 32)
    private String cashier;

    @Column(name = "intl_ticket")
    private Integer intlTicket;

    /**
     * 退票单号
     */
    @Column(name = "refund_order_no", length = 10)
    private String refundOrderNo;

    /**
     * 订单号(该退票来自哪个机票订单）
     */
    @Column(name = "order_no", length = 10)
    private String orderNo;


    /**
     * 退票理由代码
     * 0-自愿退票
     * 1-非自愿退票
     * 4-废票
     */
    @Column(name = "reason_code")
    private Integer reasonCode;

    /**
     * 退票理由
     */
    @Column(name = "reason_desc")
    private String reasonDesc;


    /**
     * 退票订单的生成日期（该字段用于结算单报表，冗余字段）
     */
    @JsonFormat(pattern = "yyyy-MM-dd",timezone="GMT+8")
    @Temporal(TemporalType.DATE)
    @Column(name = "order_date")
    private Date orderDate;

    /**
     * 提交退票的日期
     */
    @JsonFormat(pattern = "yyyy-MM-dd",timezone="GMT+8")
    @Temporal(TemporalType.DATE)
    @Column(name = "submit_date")
    private Date submitDate;

    /**
     * 航司退票日期
     */
    @JsonFormat(pattern = "yyyy-MM-dd",timezone="GMT+8")
    @Temporal(TemporalType.DATE)
    @Column(name = "air_refund_date")
    private Date airlineRefundDate;

    /**
     * 实退客户日期
     */
    @JsonFormat(pattern = "yyyy-MM-dd",timezone="GMT+8")
    @Temporal(TemporalType.DATE)
    @Column(name = "psg_refund_date")
    private Date psgRefundDate;

    /**
     * 是否已付款（退款给客人的意思）
     */
    @Column(name = "be_paid", length = 1)
    private String bePaid;

    private String remark;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "create_time", insertable = false, updatable = false)
    private Date createTime;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "last_update", insertable = false)
    private Date lastUpdate;

    @Transient
    private List<FlightInfo> flights;

    public double getProfit() {
        double f = getAirlineRefundAmount() - getPassengerRefundAmount();
        return DecimalUtil.keepScale2(f);
    }



    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getEnterpriseId() {
        return enterpriseId;
    }

    public void setEnterpriseId(int enterpriseId) {
        this.enterpriseId = enterpriseId;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }


    public String getTicketNo() {
        return ticketNo;
    }

    public void setTicketNo(String ticketNo) {
        this.ticketNo = ticketNo;
    }

    public String getPsgName() {
        return psgName;
    }

    public void setPsgName(String psgName) {
        this.psgName = psgName;
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    public String getBalanceCode() {
        return balanceCode;
    }

    public void setBalanceCode(String balanceCode) {
        this.balanceCode = balanceCode;
    }

    public double getTicketAmount() {
        return ticketAmount;
    }

    public void setTicketAmount(double ticketAmount) {
        this.ticketAmount = ticketAmount;
    }

    public double getServiceCharge() {
        return serviceCharge;
    }

    public void setServiceCharge(double serviceCharge) {
        this.serviceCharge = serviceCharge;
    }

    public double getAirRefundCharge() {
        return airRefundCharge;
    }

    public void setAirRefundCharge(double airRefundCharge) {
        this.airRefundCharge = airRefundCharge;
    }

    public void setOperator(String operator) {
        this.operator = operator;
    }

    public String getOperator() {
        return operator;
    }

    public double getAirlineRefundAmount() {
        return airlineRefundAmount == null ? 0 : airlineRefundAmount;
    }

    public void setAirlineRefundAmount(Double airlineRefundAmount) {
        this.airlineRefundAmount = airlineRefundAmount;
    }

    public double getPassengerRefundAmount() {
        return passengerRefundAmount == null ? 0 : passengerRefundAmount;
    }

    public void setPassengerRefundAmount(Double passengerRefundAmount) {
        this.passengerRefundAmount = passengerRefundAmount;
    }

    public Date getLastUpdate() {
        return lastUpdate;
    }

    public void setLastUpdate(Date lastUpdate) {
        this.lastUpdate = lastUpdate;
    }

    public String getBillNum() {
        return billNum;
    }

    public void setBillNum(String billNum) {
        this.billNum = billNum;
    }

    public Integer getCustomerType() {
        return customerType;
    }

    public void setCustomerType(Integer customerType) {
        this.customerType = customerType;
    }

    public String getCashier() {
        return cashier;
    }

    public void setCashier(String cashier) {
        this.cashier = cashier;
    }

    public String getTicketer() {
        return ticketer;
    }

    public void setTicketer(String ticketer) {
        this.ticketer = ticketer;
    }

    public void setIntlTicket(int intlTicket) {
        this.intlTicket = intlTicket;
    }

    public int getIntlTicket() {
        return intlTicket == null ? 0 : intlTicket;
    }

    public String getRefundOrderNo() {
        return refundOrderNo;
    }

    public void setRefundOrderNo(String refundOrderNo) {
        this.refundOrderNo = refundOrderNo;
    }

    public int getReasonCode() {
        return reasonCode == null ? 0 : reasonCode;
    }

    public void setReasonCode(Integer reasonCode) {
        this.reasonCode = reasonCode;
    }

    public String getReasonDesc() {
        return reasonDesc;
    }

    public void setReasonDesc(String reasonDesc) {
        this.reasonDesc = reasonDesc;
    }

    public String getOrderNo() {
        return orderNo;
    }

    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }

    public Date getSubmitDate() {
        return submitDate;
    }

    public void setSubmitDate(Date submitDate) {
        this.submitDate = submitDate;
    }

    public Date getAirlineRefundDate() {
        return airlineRefundDate;
    }

    public void setAirlineRefundDate(Date airlineRefundDate) {
        this.airlineRefundDate = airlineRefundDate;
    }

    public Date getPsgRefundDate() {
        return psgRefundDate;
    }

    public void setPsgRefundDate(Date psgRefundDate) {
        this.psgRefundDate = psgRefundDate;
    }

    public Integer getCustomerId() {
        return customerId;
    }

    public void setCustomerId(Integer customerId) {
        this.customerId = customerId;
    }

    public List<FlightInfo> getFlights() {
        if (flights == null) {
          flights = new ArrayList<>();
        }
        return flights;
    }

    public void setFlights(List<FlightInfo> flights) {
        this.flights = flights;
    }

    public String getFlightNo() {
        return getFlights().isEmpty() ? "" : getFlights().get(0).getFlightNo();
    }

    public String getSubclass() {
        return getFlights().isEmpty() ? "" : getFlights().get(0).getSubclass();
    }

    public String getDport() {
        return getFlights().isEmpty() ? "" : getFlights().get(0).getDepartureAirport();
    }

    public String getDportName() {
        return getFlights().size() == 0 ? "" : getFlights().get(0).getDepartureAirportName();
    }

    public String getAport() {
        return getFlights().isEmpty() ? "" : getFlights().get(0).getArrivalAirport();
    }

    public String getAportName() {
        return getFlights().size() == 0 ? "" : getFlights().get(0).getArrivalAirportName();
    }

    public String getDterm() {
        return getFlights().size() == 0 ? "" : getFlights().get(0).getDepartureTerminal();
    }

    public String getAterm() {
        return getFlights().size() == 0 ? "" : getFlights().get(0).getArrivalTerminal();
    }

    public String getDdate() {
        return getFlights().size() == 0 ? "" : getFlights().get(0).getDepartureDate();
    }

    public String getDtime() {
        return getFlights().size() == 0 ? "" : getFlights().get(0).getDepartureTime();
    }

    public String getAtime() {
        return getFlights().size() == 0 ? "" : getFlights().get(0).getArrivalTime();
    }

    public String getBePaid() {
        return bePaid;
    }

    public void setBePaid(String bePaid) {
        this.bePaid = bePaid;
    }

    public String getPnrNo() {
        return pnrNo;
    }

    public void setPnrNo(String pnrNo) {
        this.pnrNo = pnrNo;
    }

    public Date getOrderDate() {
        return orderDate;
    }

    public void setOrderDate(Date orderDate) {
        this.orderDate = orderDate;
    }
}
